package com.coin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coin.domain.*;
import com.coin.dto.CoinDto;
import com.coin.feign.CoinServiceFeign;
import com.coin.mapper.TradeAreaMapper;
import com.coin.service.*;
import com.coin.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 李力
 * @description 针对表【trade_area(交易区)】的数据库操作Service实现
 * @createDate 2025-06-20 14:51:04
 */
@Service
public class TradeAreaServiceImpl extends ServiceImpl<TradeAreaMapper, TradeArea>
        implements TradeAreaService {

    @Autowired
    private MarketService marketService;

    @Autowired
    private CoinServiceFeign coinServiceFeign;

    @Autowired
    private UserFavoriteMarketService favoriteMarketService;

    /**
     * @Description: 交易区域的分页查询
     * @Author: 李 力
     * @Date: 2025/6/20
     * @Param:
     * @return: R
     */
    @Override
    public Page<TradeArea> findByPage(Page<TradeArea> page, String name, Byte status) {
        LambdaQueryWrapper<TradeArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.like(StrUtil.isNotEmpty(name), TradeArea::getName, name)
                .eq(status != null, TradeArea::getStatus, status);
        return page(page, queryWrapper);
    }

    /**
     * @Description: 新增一个交易区域
     * @Author: 李 力
     * @Date: 2025/6/20
     * @Param:
     * @return: R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTradeArea(TradeArea tradeArea) {
        if (tradeArea == null) {
            throw new RuntimeException("参数为空");
        }
        return save(tradeArea);
    }

    /**
     * @Description: 修改一个交易区域
     * @Author: 李 力
     * @Date: 2025/6/20
     * @Param:
     * @return: R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTradeArea(TradeArea tradeArea) {
        if (tradeArea == null) {
            throw new RuntimeException("参数为空");
        }
        return updateById(tradeArea);
    }

    /**
     * @Description: 修改一个交易区域的状态
     * @Author: 李 力
     * @Date: 2025/6/20
     * @Param:
     * @return: R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(TradeArea tradeArea) {
        if (tradeArea == null) {
            throw new RuntimeException("参数为空");
        }
        return updateById(tradeArea);
    }

    /**
     * @Description: 根据状态查询交易区域
     * @Author: 李 力
     * @Date: 2025/6/20
     * @Param:
     * @return: R
     */
    @Override
    public List<TradeArea> findAll(Byte status) {
        LambdaQueryWrapper<TradeArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(status != null, TradeArea::getStatus, status);
        return list(queryWrapper);
    }

    /**
     * @Description: 交易区域查询
     * @Author: 李 力
     * @Date: 2025/6/21
     * @Param:
     * @return: R
     */
    @Override
    public List<TradeAreaMarketVo> findTradeArea() {
        //查询所有的交易区域
        LambdaQueryWrapper<TradeArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(TradeArea::getStatus, 1)
                .orderByAsc(TradeArea::getSort);
        List<TradeArea> tradeAreas = list(queryWrapper);
        if (tradeAreas == null || tradeAreas.isEmpty()) {
            return null;
        }
        List<TradeAreaMarketVo> marketVoList = new ArrayList<>();
        for (TradeArea tradeArea : tradeAreas) {
            //查询交易区域下的市场
            List<Market> markets = marketService.getMarkets(tradeArea.getId());
            if (markets != null && !markets.isEmpty()) {
                TradeAreaMarketVo tradeAreaMarketVo = new TradeAreaMarketVo();
                tradeAreaMarketVo.setAreaName(tradeArea.getName());
                tradeAreaMarketVo.setMarkets(marketsToTradeMarketVos(markets));
                marketVoList.add(tradeAreaMarketVo);
            }
        }
        return marketVoList;
    }

    private List<TradeMarketVo> marketsToTradeMarketVos(List<Market> markets) {
        List<TradeMarketVo> voList = markets.stream().map(
                market -> convertVo(market)
        ).collect(Collectors.toList());
        return voList;
    }

    private TradeMarketVo convertVo(Market market) {
        TradeMarketVo tradeMarketVo = new TradeMarketVo();
        tradeMarketVo.setImage(market.getImg());
        tradeMarketVo.setName(market.getName());
        tradeMarketVo.setSymbol(market.getSymbol());
        tradeMarketVo.setHigh(market.getOpenPrice()); // OpenPrice 开盘价格
        tradeMarketVo.setLow(market.getOpenPrice()); // 获取K线数据
        tradeMarketVo.setPrice(market.getOpenPrice()); // 获取K线数据
        Long buyCoinId = market.getBuyCoinId();
        List<CoinDto> coins = coinServiceFeign.findCoins(Arrays.asList(buyCoinId));
        if (coins == null || coins.isEmpty()) {
            throw new RuntimeException("报价货币错误");
        }
        CoinDto coinDto = coins.get(0);
        tradeMarketVo.setPriceUnit(coinDto.getName()); // 报价货币的名称
        // 设置交易量
        tradeMarketVo.setVolume(BigDecimal.ZERO); // // 日的总交易量
        tradeMarketVo.setAmount(BigDecimal.ZERO); // 日的总的交易额
        tradeMarketVo.setChange(0.00);
        // 交易的额度
        tradeMarketVo.setTradeMin(market.getTradeMin());
        tradeMarketVo.setTradeMax(market.getTradeMax());
        // 下单的数量限制
        tradeMarketVo.setNumMin(market.getNumMin());
        tradeMarketVo.setNumMax(market.getNumMax());
        // 手续费的设置
        tradeMarketVo.setSellFeeRate(market.getFeeSell());
        tradeMarketVo.setBuyFeeRate(market.getFeeBuy());
        // 价格的小数的位数
        tradeMarketVo.setNumScale(market.getNumScale());
        //  排序
        tradeMarketVo.setSort(market.getSort());
        // 设置合并的深度
        tradeMarketVo.setMergeDepth(getMergeDepths(market.getMergeDepth()));
        tradeMarketVo.setCnyPrice(market.getOpenPrice()); // 计算获得
        return tradeMarketVo;
    }

    private List<MergeDeptVo> getMergeDepths(String mergeDepth) {
        String[] split = mergeDepth.split(",");
        if (split.length != 3) {
            throw new IllegalArgumentException("合并深度不合法");
        }
        MergeDeptVo minMergeDeptVo = new MergeDeptVo();
        minMergeDeptVo.setMergeType("MIN"); //
        minMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[0])));
        MergeDeptVo defaultMergeDeptVo = new MergeDeptVo();
        defaultMergeDeptVo.setMergeType("DEFAULT"); //
        defaultMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[1])));
        MergeDeptVo maxMergeDeptVo = new MergeDeptVo();
        maxMergeDeptVo.setMergeType("MAX"); //
        maxMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[2])));
        List<MergeDeptVo> mergeDeptVos = new ArrayList<>();
        mergeDeptVos.add(minMergeDeptVo);
        mergeDeptVos.add(defaultMergeDeptVo);
        mergeDeptVos.add(maxMergeDeptVo);
        return mergeDeptVos;
    }

    private BigDecimal getDeptValue(Integer scale) {
        BigDecimal bigDecimal = new BigDecimal(Math.pow(10, scale)); // Math.pow(10, scale) 指数操作
        return BigDecimal.ONE.divide(bigDecimal).setScale(scale, RoundingMode.HALF_UP); // 1/10^n
    }

    /**
     * @Description: 用户收藏的交易市场查询
     * @Author: 李 力
     * @Date: 2025/6/23
     * @Param:
     * @return: R
     */
    @Override
    public List<TradeAreaMarketVo> getUserFavoriteMarkets(Long userId) {
        LambdaQueryWrapper<UserFavoriteMarket> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(userId != null, UserFavoriteMarket::getUserId, userId);
        List<UserFavoriteMarket> favoriteMarkets = favoriteMarketService.list(queryWrapper);
        if (CollectionUtil.isEmpty(favoriteMarkets)) {
            return null;
        }
        List<Long> marketIds = favoriteMarkets.stream().map(UserFavoriteMarket::getMarketId).collect(Collectors.toList());
        TradeAreaMarketVo marketVo = new TradeAreaMarketVo();
        List<Market> marketList = marketService.listByIds(marketIds);
        List<TradeMarketVo> voList = marketsToTradeMarketVos(marketList);
        marketVo.setAreaName("自选");
        marketVo.setMarkets(voList);
        return Arrays.asList(marketVo);
    }
}




